package nl.infodation.emr.pricingservice.ui.component;

import java.util.Arrays;
import java.util.Locale;

import nl.infodation.emr.utility.I18NPricingLangSupport;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.peholmst.i18n4vaadin.I18N;
import com.github.peholmst.i18n4vaadin.I18NComponent;
import com.github.peholmst.i18n4vaadin.I18NListener;
import com.github.peholmst.i18n4vaadin.ResourceBundleI18N;
import com.github.peholmst.i18n4vaadin.support.I18NComponentSupport;
import com.vaadin.ui.Panel;

public abstract class AbstractBasePanel extends Panel implements I18NComponent, I18NListener {
	
	private static final long serialVersionUID = 2L;
	protected static final Logger LOG = LoggerFactory.getLogger(AbstractBasePanel.class);
	private I18NComponentSupport support = new I18NComponentSupport(this); // must be none-static
	
	protected void initialize() {
		initLayout();
		this.setSizeFull();
	}
	
	@Override
	public I18N getI18N() {
		synchronized (support) {
			if (support.getI18N() == null) {
				final I18N i18n = new ResourceBundleI18N("messages", Locale.ENGLISH, Locale.FRENCH, Locale.forLanguageTag("nl"));
				support.setI18N(i18n);
			}
		}
		return support.getI18N();
	}
	
	/**
	 * 
	 * @param locale new Locale to switch interface to
	 * @return new Locale that was set.
	 */
	public Locale switchLocale(final Locale locale) {
		LOG.debug("Switch locale to " + locale);
			if (locale != null) {
					if (!locale.equals(getI18N().getCurrentLocale())) {
						
						if (getI18N().getSupportedLocales().contains(locale)) {
								getI18N().setCurrentLocale(locale);
								localeChanged(getI18N(), null, I18NPricingLangSupport.getCurrentLang());
								setLocale(locale);
								I18NPricingLangSupport.setCurrentLang(locale);
								
						} else {
							final Locale only_lan = Locale.forLanguageTag(locale.getLanguage());
							if (! only_lan.equals(getI18N().getCurrentLocale())) {
								if (getI18N().getSupportedLocales().contains(only_lan)) {
									LOG.debug("Switch locale to language only version: " + only_lan);
									getI18N().setCurrentLocale(only_lan);
									localeChanged(getI18N(), null, I18NPricingLangSupport.getCurrentLang());
									setLocale(only_lan);
									I18NPricingLangSupport.setCurrentLang(locale);
									
								} else {
									LOG.warn("Requested Locale {} not supported in current locales: {}"
											, locale
											, Arrays.toString(support.getI18N().getSupportedLocales().toArray())
										);
								}
							}
						}
					}
			}
			return getI18N().getCurrentLocale();
	}
	
	public void localeChanged(final I18N sender, final Locale oldLocale, final Locale newLocale) {
		I18NPricingLangSupport.localeChanged(sender, oldLocale, newLocale, getComponentIterator());
	}
	
	@Override
	public void attach() {
	        super.attach();
	        getI18N().addListener(this); // Register listener
	        final Locale userLocale = getLocale();
	    	LOG.debug("user prefers locale {}", userLocale);
	    	if (I18NPricingLangSupport.getCurrentLang() == null || ! I18NPricingLangSupport.getCurrentLang().equals(userLocale)) {
	    		I18NPricingLangSupport.setCurrentLang(switchLocale(userLocale));
		    		LOG.debug("Set to Locale {}", I18NPricingLangSupport.getCurrentLang());
	    	}
	}

    @Override
    public void detach() {
        // Remember to unregister listener as well!
        getI18N().removeListener(this);
        super.detach();
    }
	
	public abstract void initLayout();
	public abstract void reload();
}
